#pragma once

namespace ezstl {

template <typename T1, typename T2>
void construct(T1 *p, const T2 &value) {
  ::new (p) T1(value);
}
/*
template<typename T, typename ...Args>
void construct(T *p, Args &&...args) {
  ::new (p) T(std::forward<Args>(args)...); // TODO: perfect forware
}
*/

template <typename T>
void construct(T *p) {
  ::new (p) T();
}

template <typename T>
void destroy(T *p) {
  p->~T();
}

template <typename ForwardIterator>
void destroy(ForwardIterator first, ForwardIterator last) {
  for (; first != last; ++first) destroy(&*first);
}

template <typename ForwardIterator, typename Size>
void destroy_n(ForwardIterator first, Size count) {
  for (; count > 0; ++first, --count) destroy(&*first);
}

}  // namespace ezstl